#include "SingleLinked.h"


using namespace std;

SingleLinked::SingleLinked()
{
    head = nullptr;
    cur = nullptr;
    cnt = 0;
    cur_cnt = 0;
}

SingleLinked::~SingleLinked()
{
    ListNode *p = head;

    ListNode** p_bk = new ListNode*[cnt];
    int i = 0;

    /* Iterate this linked-list and back up the pointer to
     * every node.
     */
    while(p != nullptr)
    {
        p_bk[i++] = p;
        p = p->next;
    }

    /* free them */
    while(--i >= 0)
    {
        allocat.deallocate(p_bk[i], 1);
    }

    head = nullptr;
    cur = nullptr;
    cnt = 0;
    cur_cnt = 0;
    delete [] p_bk;
}
/**/
int SingleLinked::deleteItem(const wchar_t &c)
{
    ListNode* p = head;
    ListNode* b = nullptr;

    //1: The head is null
    //2: The head is not null and the target node is head.
    if(p == nullptr)
    {
        return -1;
    }
    else if(p->ch == c)
    {
        return 1;
    }
    //3: The target node is some one but not last node
    //4: The target node is last node.
    //5: The target node is not in the list.

    p = head->next;

    while(p != nullptr && p->ch != c)
    {
        b = p;
        p = p->next;
    }

    if(p != nullptr)
    {
        b->next = p->next;
        allocat.deallocate(p, 1);
        cnt--;
        return 0;
    }
    else
    {
        return 2;
    }

}
/**/
int SingleLinked::addItem(const wchar_t &c)
{
    ListNode* n = nullptr;
    ListNode** p = nullptr;


    n = (ListNode *)allocat.allocate(1);
    n->ch = c;
    n->next = nullptr;

    /* !! Code below takes lots of times !! */
    /* !! Use a pointer to pointer !!*/
    p = &head;

    /* Search it to a null pointer */
    while(*p != nullptr)
    {
        p = &((*p)->next);
    }
    /* It means (*p)->next = n */
    *p = n;

    cnt++;

    return 0;
}
/**/
int SingleLinked::getSize(void)
{
    return cnt;
}
/**/
void SingleLinked::setItemIdx(const int &i)
{
    if(i > cnt)
        return;
    cur_cnt = i;
}
/**/
wchar_t SingleLinked::nextItem(void)
{
    wchar_t c = 0;

    if(head == nullptr)
    {
        return c;
    }
    else if(cur == nullptr && cur_cnt == 0)
    {
        cur = head;
    }

    if(cur != nullptr && cur_cnt != cnt)
    {
       c = cur->ch;
       cur = cur->next;
       cur_cnt++;
    }

    return c;

}
/**/

